package com.example.unique.ui.contact

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.services.geocoder.GeocodeQuery
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeResult
import com.example.unique.database.DatabaseHelper
import com.example.unique.database.DatabaseJob
import com.example.unique.database.DatabaseTaskCompletion
import com.example.unique.databinding.ContactBinding
import com.google.android.gms.maps.model.LatLng
import java.io.File
import java.text.SimpleDateFormat
import java.util.*

class ContactFragment : Fragment() {

    private var _binding: ContactBinding? = null
    private val binding get() = _binding!!
    private lateinit var club: String
    private lateinit var sno: String
    private lateinit var taskName: String
    private lateinit var jobDatabaseJob: DatabaseJob
    private lateinit var taskCompletion: DatabaseTaskCompletion
    private lateinit var contactViewModel: ContactViewModel
    private lateinit var userDatabase: DatabaseHelper

    private lateinit var locationClient: AMapLocationClient
    private var taskRadius: Double = 0.0

    private lateinit var geocodeSearch: GeocodeSearch
    private lateinit var targetLatLng: LatLng
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        club = activity?.intent?.getStringExtra("club").toString()
        sno = activity?.intent?.getStringExtra("sno").toString()
        taskName = arguments?.getString("taskName").toString()

        jobDatabaseJob = DatabaseJob.getInstance(requireContext())
        userDatabase = DatabaseHelper(requireContext())
        taskCompletion = DatabaseTaskCompletion.getInstance(requireContext())
        contactViewModel = ContactViewModel(jobDatabaseJob, taskCompletion)
        contactViewModel.getTargetJobInfo(club, taskName)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = ContactBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // 观察任务信息
        // 初始化地理编码服务
        geocodeSearch = GeocodeSearch(requireContext())
        geocodeSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
            override fun onGeocodeSearched(result: GeocodeResult?, rCode: Int) {
                if (rCode == 1000 && result != null && result.geocodeAddressList.isNotEmpty()) {
                    val latLonPoint = result.geocodeAddressList[0].latLonPoint
                    targetLatLng = LatLng(latLonPoint.latitude, latLonPoint.longitude)
                    Toast.makeText(requireContext(), "位置解析成功: $targetLatLng", Toast.LENGTH_SHORT).show()

                    // 启动位置更新
                    startLocationUpdates()
                } else {
                    Toast.makeText(requireContext(), "未找到指定地址", Toast.LENGTH_SHORT).show()
                }
            }

            override fun onRegeocodeSearched(result: RegeocodeResult?, rCode: Int) {}
        })

        contactViewModel.completeInfo.observe(viewLifecycleOwner) { complete ->
            if(complete!=null){
                binding.taskTitle.text = "任务标题：${complete.taskName}"
                binding.taskStartTime.text = "发布时间：${complete.startTime}"
                binding.taskDeadline.text = "截止时间：${complete.endTime}"
                binding.taskLocation.text="任务位置：${complete.target}(范围${complete.radius}米)"
                val qrCodeBitmap = loadQRCodeFromFile(complete.qrCodeUri)
                if (qrCodeBitmap != null) {
                    binding.taskQrCode.setImageBitmap(qrCodeBitmap)
                } else {
                    Log.e("ContactFragment", "加载二维码失败: ${complete.qrCodeUri}")
                }
                // 如果任务位置为地名，则通过地理编码解析
                if (!complete.target.contains(",")) {
                    getLatLngFromAddress(complete.target)
                } else {
                    // 如果是经纬度格式，直接解析
                    targetLatLng = parseLatLng(complete.target)
                    taskRadius = complete.radius
                    startLocationUpdates()
                }
            }
        }

        binding.acceptTaskButton.setOnClickListener {
            val complete = contactViewModel.completeInfo.value
            if (complete != null) {
                if (isWithinTimeRange(complete.startTime, complete.endTime)) {
                    if (binding.scanResult.text.isNotEmpty()) {
                        val expectedCode = binding.scanResult.text.toString()
                        showInputCodeDialog(expectedCode) {
                            // 验证成功后的逻辑
                            jobDatabaseJob.updateStatus(club, taskName, 2)
                            taskCompletion.updateIsCompleted(club, taskName, sno, 1)
                            Toast.makeText(requireContext(), "打卡成功！", Toast.LENGTH_SHORT).show()
                        }
                    } else {
                        Toast.makeText(requireContext(), "请先长按二维码生成口令！", Toast.LENGTH_SHORT).show()
                    }
                } else {
                    Toast.makeText(requireContext(), "不在任务时间范围内，无法打卡！", Toast.LENGTH_SHORT).show()
                }
            }
        }

        // 二维码长按生成唯一代码
        binding.taskQrCode.setOnLongClickListener {
            val checkInCode = generateRandomCheckInCode()
            binding.scanResult.text = checkInCode
            // 将生成的代码复制到剪贴板
            val clipboardManager = requireContext().getSystemService(android.content.Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager
            val clipData = android.content.ClipData.newPlainText("Check-In Code", checkInCode)
            clipboardManager.setPrimaryClip(clipData)
            Toast.makeText(requireContext(), "生成打卡代码：$checkInCode", Toast.LENGTH_SHORT).show()
            true
        }
    }
    // 获取指定地址的经纬度
    private fun getLatLngFromAddress(address: String) {
        val query = GeocodeQuery(address, "") // 第二个参数为城市编码，可为空
        geocodeSearch.getFromLocationNameAsyn(query)
    }

    // 从文件加载二维码
    private fun loadQRCodeFromFile(filePath: String): Bitmap? {
        val file = File(filePath)
        if (!file.exists()) {
            Log.e("ContactFragment", "二维码文件不存在: $filePath")
            Toast.makeText(requireContext(), "二维码加载失败", Toast.LENGTH_SHORT).show()
            return null
        }
        return BitmapFactory.decodeFile(file.absolutePath)
    }

    // 校验时间范围
    private fun isWithinTimeRange(startTime: String, endTime: String): Boolean {
        val currentTime = System.currentTimeMillis()
        val format = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
        val start = format.parse(startTime)?.time ?: 0
        val end = format.parse(endTime)?.time ?: 0
        return currentTime in start..end
    }

    // 解析 LatLng
    private fun parseLatLng(target: String): LatLng {
        try {
            val parts = target.split(",")
            if (parts.size != 2) {
                throw IllegalArgumentException("目标位置格式错误: $target")
            }
            return LatLng(parts[0].toDouble(), parts[1].toDouble())
        } catch (e: Exception) {
            Log.e("ContactFragment", "解析目标位置失败: ${e.message}")
            throw e // 根据需求决定是否抛出异常或使用默认值
        }
    }


    // 定位更新
    private fun startLocationUpdates() {
        locationClient = AMapLocationClient(requireContext())
        locationClient.setLocationListener { location ->
            if (location != null && location.errorCode == 0) {
                val currentLatLng = LatLng(location.latitude, location.longitude)
                val distance = calculateDistance(currentLatLng, targetLatLng)
                Toast.makeText(requireContext(), "距离目标位置：$distance 米", Toast.LENGTH_SHORT).show()

                if (distance <= taskRadius) {
                    binding.acceptTaskButton.isEnabled = true
                    Toast.makeText(requireContext(), "状态：可打卡", Toast.LENGTH_SHORT).show()
                } else {
                    binding.acceptTaskButton.isEnabled = false
                    Toast.makeText(requireContext(), "状态：超出范围", Toast.LENGTH_SHORT).show()
                }
            } else {
                Log.e("ContactFragment", "定位失败：${location?.errorInfo}")
            }
        }

        val locationOption = AMapLocationClientOption().apply {
            locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
            isNeedAddress = false
            interval = 5000 // 5秒更新一次
        }

        locationClient.setLocationOption(locationOption)
        locationClient.startLocation()
    }

    // 计算两点之间的距离
    private fun calculateDistance(current: LatLng, target: LatLng): Double {
        val earthRadius = 6371000.0 // 地球半径，单位：米
        val dLat = Math.toRadians(target.latitude - current.latitude)
        val dLon = Math.toRadians(target.longitude - current.longitude)
        val a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(Math.toRadians(current.latitude)) * Math.cos(Math.toRadians(target.latitude)) *
                Math.sin(dLon / 2) * Math.sin(dLon / 2)
        val c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
        return earthRadius * c
    }

    // 生成随机的打卡代码
    private fun generateRandomCheckInCode(): String {
        val characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
        return (1..8).map { characters.random() }.joinToString("")
    }
    private fun showInputCodeDialog(expectedCode: String, onSuccess: () -> Unit) {
        val inputEditText = android.widget.EditText(requireContext())
        val dialog = androidx.appcompat.app.AlertDialog.Builder(requireContext())
            .setTitle("输入打卡口令")
            .setMessage("请输入正确的口令进行打卡验证")
            .setView(inputEditText)
            .setPositiveButton("确认") { _, _ ->
                val inputCode = inputEditText.text.toString()
                if (inputCode == expectedCode) {
                    onSuccess()
                } else {
                    Toast.makeText(requireContext(), "口令错误，无法打卡！", Toast.LENGTH_SHORT).show()
                }
            }
            .setNegativeButton("取消") { dialog, _ ->
                dialog.dismiss()
            }
            .create()
        dialog.show()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
        locationClient.stopLocation()
        locationClient.onDestroy()
    }
}
